package com.zt.bus.wx.controller;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zt.bus.constant.BusConstant;
import com.zt.bus.order.model.OrderPayment;
import com.zt.bus.order.service.OrderPaymentService;
import com.zt.bus.util.CollectionUtil;
import com.zt.bus.util.FileUtil;
import com.zt.bus.wx.service.WxPayService;
import com.zt.bus.wx.util.HttpUtils;
import com.zt.bus.wx.util.PayUtil;
import com.zt.bus.wx.util.XmlUtil;
import com.zt.servlet.Response;
import com.zt.util.PropertiesUtil;
import com.zt.util.StringUtil;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 创建时间：2016年11月2日 下午4:16:32
 * 
 * @author andy
 * @version 2.2
 */
@Controller
@RequestMapping("/wxpay")
public class WxPayController {

	private static final Logger LOG = Logger.getLogger(WxPayController.class);

	@Autowired
	private OrderPaymentService orderPaymentService;

	private static final String ORDER_PAY = "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 统一下单

	private static final String ORDER_PAY_QUERY = "https://api.mch.weixin.qq.com/pay/orderquery"; // 支付订单查询

	private static final String ORDER_REFUND = "https://api.mch.weixin.qq.com/secapi/pay/refund"; // 申请退款

	private static final String ORDER_REFUND_QUERY = "https://api.mch.weixin.qq.com/pay/refundquery"; // 申请退款

	private static final String APP_ID = PropertiesUtil.getProperty("wxAppPay.appId");

	private static final String MCH_ID = PropertiesUtil.getProperty("wxAppPay.mchId");

	private static final String API_SECRET = PropertiesUtil.getProperty("wxAppPay.mchKey");


	/**
	 * 支付下订单
	 * 
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/pay", method = RequestMethod.POST)
	@ResponseBody
	public JSONObject orderPay(HttpServletRequest request, HttpServletResponse response) {
		LOG.info("[/wx/pay]");
//		if (!"001".equals(mercid)) {
//			WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//					.toJSONString(new JsonResult(-1, "商品不存在", new ResponseData()), SerializerFeatureUtil.FEATURES)));
//		}

		String phone = request.getParameter("phone");
		String orderId = request.getParameter("orderId");

		if(StringUtil.isEmpty(phone) || StringUtil.isEmpty(orderId)) {
			return Response.responseError("订单号或手机号码为空");
		}


		Double cashnum = 0.02;

		Map<String, String> restmap = null;
		boolean flag = true; // 是否订单创建成功
		//得到订单信息
		OrderPayment orderPayment = orderPaymentService.getOrderPayment(BusConstant.PayPlatform.WEIXIN_APP, orderId, phone);
		try {
			String total_fee = BigDecimal.valueOf(cashnum).multiply(BigDecimal.valueOf(100))
					.setScale(0, BigDecimal.ROUND_HALF_UP).toString();
			Map<String, String> parm = new HashMap<String, String>();
			parm.put("appid", APP_ID);
			parm.put("mch_id", MCH_ID);
			parm.put("device_info", "WEB");
			parm.put("nonce_str", PayUtil.getNonceStr());
			parm.put("body", "定制公交订单号:" + orderId);
			parm.put("attach", "Andy");
			parm.put("out_trade_no", orderPayment.getTradeNo());
			parm.put("total_fee", total_fee);
			parm.put("spbill_create_ip", PayUtil.getRemoteAddrIp(request));
			parm.put("notify_url", "http://investor.lingducapital.com/custom-bus/wxpay/pay/notify.do"); //微信服务器异步通知支付结果地址  下面的order/notify 方法
			parm.put("trade_type", "APP");
			parm.put("sign", PayUtil.getSign(parm, API_SECRET));

			String restxml = HttpUtils.post(ORDER_PAY, XmlUtil.xmlFormat(parm, false));
			restmap = XmlUtil.xmlParse(restxml);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}

		Map<String, String> payMap = new HashMap<String, String>();
		if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
			payMap.put("appid", APP_ID);
			payMap.put("partnerid", MCH_ID);
			payMap.put("prepayid", restmap.get("prepay_id"));
			payMap.put("package", "Sign=WXPay");
			payMap.put("noncestr", PayUtil.getNonceStr());
			payMap.put("timestamp", PayUtil.payTimestamp());
			try {
				payMap.put("sign", PayUtil.getSign(payMap, API_SECRET));
			} catch (Exception e) {
				flag = false;
			}
		} else {
			flag = false;
		}

		if (flag) {
			payMap.put("packageStr", "Sign=WXPay");
			payMap.put("nonceStr", payMap.get("noncestr"));
			payMap.put("timeStamp", payMap.get("timestamp"));
			payMap.put("paySign", payMap.get("sign"));
			System.out.println(JSONObject.fromObject(payMap));

			//成功，插入订单信息
			orderPaymentService.createOrderPayment(orderPayment);
			JSONObject json = new JSONObject();
			json.put("params",JSONObject.fromObject(payMap));
			json.put("out_trade_no", orderPayment.getTradeNo());
			return Response.response(json);
		} else {
			if (CollectionUtil.isNotEmpty(restmap)) {
				LOG.info("订单创建失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
			}
			return Response.responseError(JSONObject.fromObject(restmap));
		}
	}

	
	/**
	 * 查询支付结果
	 * 
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/pay/query", method = RequestMethod.POST)
	public void orderPayQuery(HttpServletRequest request, HttpServletResponse response) {
		LOG.info("[/wx/pay/query]");
		String tradeid = "4009202001201706094930401803"; //微信交易订单号 transaction_id
		String tradeno = "TNO2017060910000662900000001"; //商户订单号 out_trade_no
		if (StringUtil.isEmpty(tradeno) && StringUtil.isEmpty(tradeid)) {
//			WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//					.toJSONString(new JsonResult(-1, "订单号不能为空", new ResponseData()), SerializerFeatureUtil.FEATURES)));
		}

		Map<String, String> restmap = null;
		try {
			Map<String, String> parm = new HashMap<String, String>();
			parm.put("appid", APP_ID);
			parm.put("mch_id", MCH_ID);
			parm.put("transaction_id", tradeid);
//			parm.put("out_trade_no", tradeno);
			parm.put("nonce_str", PayUtil.getNonceStr());
			parm.put("sign", PayUtil.getSign(parm, API_SECRET));

			String restxml = HttpUtils.post(ORDER_PAY_QUERY, XmlUtil.xmlFormat(parm, false));
			restmap = XmlUtil.xmlParse(restxml);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}

		if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
			// 订单查询成功 处理业务逻辑
			LOG.info("订单查询：订单" + restmap.get("out_trade_no") + "支付成功");
//			WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//					.toJSONString(new JsonResult(1, "订单支付成功", new ResponseData()), SerializerFeatureUtil.FEATURES)));
		} else {
			if (CollectionUtil.isNotEmpty(restmap)) {
				LOG.info("订单支付失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
			}
//			WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//					.toJSONString(new JsonResult(-1, "订单支付失败", new ResponseData()), SerializerFeatureUtil.FEATURES)));
		}
	}

	
	/**
	 * 订单支付微信服务器异步通知
	 * 
	 * @param request
	 * @param response
	 */
	@RequestMapping("/pay/notify")
	@ResponseBody
	public String orderPayNotify(HttpServletRequest request, HttpServletResponse response) {
		LOG.info("[/wx/pay/notify]");
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/xml");

		Document document = DocumentHelper.createDocument();
		Element xml = document.addElement("xml");
		Element return_code = xml.addElement("return_code");
		Element return_msg = xml.addElement("return_msg");
		try {
			ServletInputStream in = request.getInputStream();
			String resxml = FileUtil.readInputStream2String(in);
			Map<String, String> restmap = XmlUtil.xmlParse(resxml);
			LOG.info("支付结果通知：" + restmap);
			if ("SUCCESS".equals(restmap.get("return_code"))) {
				// 订单支付成功 业务处理
				String out_trade_no = restmap.get("out_trade_no"); // 商户订单号
				// 通过商户订单判断是否该订单已经处理 如果处理跳过 如果未处理先校验sign签名 再进行订单业务相关的处理
				String transaction_id = restmap.get("transaction_id");
				String sing = restmap.get("sign"); // 返回的签名
				restmap.remove("sign");
				String signnow = PayUtil.getSign(restmap, API_SECRET);
				if (signnow.equals(sing)) {
					// 进行业务处理
					//回调成功，设置微信回调交易号，修改状态
					orderPaymentService.paymentSetResult(out_trade_no, transaction_id,true,"订单支付通知： 支付成功，订单号" + out_trade_no);
					LOG.info("订单支付通知： 支付成功，订单号" + out_trade_no);

					return_code.addCDATA("SUCCESS");
					return_msg.addCDATA("OK");

				} else {
					LOG.info("订单支付通知：签名错误");
					orderPaymentService.paymentSetResult(out_trade_no, transaction_id, false, "订单支付通知：签名错误");
					return_code.addCDATA("FAIL");
					return_msg.addCDATA("订单支付通知：签名错误");
				}
			} else {
				LOG.info("订单支付通知：支付失败，" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
				return_code.addCDATA("FAIL");
				return_msg.addCDATA("订单支付通知：支付失败，" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
			}
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			return_code.addCDATA("FAIL");
			return_msg.addCDATA("回调接入失败!");
		}
		System.out.println(document.asXML());
		return document.asXML();
	}

	/**
	 * 订单退款 需要双向证书验证
	 * 
	 * @param request
	 * @param response
	 *
	 */
//	@RequestMapping(value = "/pay/refund", method = RequestMethod.POST)
//	public void orderPayRefund(HttpServletRequest request, HttpServletResponse response) {
//
//		LOG.info("[/wx/pay/refund]");
//		String tradeno = "4009202001201706094934397474"; //微信交易订单号 transaction_id
//		String orderno = "TNO2017060910261198900000001"; //商户订单号 out_trade_no
//		if (StringUtil.isEmpty(tradeno) && StringUtil.isEmpty(orderno)) {
////			WebUtil.response(response, WebUtil.packJsonp(callback, JSON
////					.toJSONString(new JsonResult(-1, "订单号不能为空", new ResponseData()), SerializerFeatureUtil.FEATURES)));
//		}
//
//		Map<String, String> restmap = null;
//		try {
//			Map<String, String> parm = new HashMap<String, String>();
//			parm.put("appid", APP_ID);
//			parm.put("mch_id", MCH_ID);
//			parm.put("nonce_str", PayUtil.getNonceStr());
//			parm.put("transaction_id", tradeno);
////			parm.put("out_trade_no", orderno);//订单号
//			parm.put("out_refund_no", PayUtil.getRefundNo()); //退款单号
//			parm.put("total_fee", "1"); // 订单总金额 从业务逻辑获取 单位分 只能为整数
//			parm.put("refund_fee", "1"); // 退款金额 单位分 只能为整数
//			parm.put("op_user_id", MCH_ID);
//			parm.put("refund_account", "REFUND_SOURCE_UNSETTLED_FUNDS");//退款方式
//			parm.put("sign", PayUtil.getSign(parm, API_SECRET));
//
//			//String restxml = HttpUtils.posts(ORDER_REFUND, XmlUtil.xmlFormat(parm, false));
//			String restxml = HttpUtils.posts(ORDER_REFUND, XmlUtil.xmlFormat(parm, false));
//			System.out.println(restxml);
//			restmap = XmlUtil.xmlParse(restxml);
//		} catch (Exception e) {
//			LOG.error(e.getMessage(), e);
//		}
//
//		Map<String, String> refundMap = new HashMap<>();
//		if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("return_code"))) {
//			if("SUCCESS".equals(restmap.get("result_code"))) {
//				refundMap.put("transaction_id", restmap.get("transaction_id"));
//				refundMap.put("out_trade_no", restmap.get("out_trade_no"));
//				refundMap.put("refund_id", restmap.get("refund_id"));
//				refundMap.put("out_refund_no", restmap.get("out_refund_no"));
//				LOG.info("订单退款：订单" + restmap.get("out_trade_no") + "退款成功，商户退款单号" + restmap.get("out_refund_no") + "，微信退款单号"
//						+ restmap.get("refund_id"));
//			} else {
//				if (CollectionUtil.isNotEmpty(restmap)) {
//					LOG.info("订单退款失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
//				}
//			}
//
//		} else {
//			if (CollectionUtil.isNotEmpty(restmap)) {
//				LOG.info("订单退款失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
//			}
//		}
//	}

	/**
	 * 订单退款查询
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/pay/refund/query", method = RequestMethod.POST)
	public void orderPayRefundQuery(HttpServletRequest request, HttpServletResponse response) {
		LOG.info("[/wx/pay/refund/query]");
//		tradeid 微信订单号
//		tradeno 商户订单号
//		refundid 微信退款号
//		refundno 商家退款号
		String tradeid = "4009202001201706094934397474"; // transaction_id 微信订单号
		if (StringUtil.isEmpty(tradeid)) {
//			WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//					.toJSONString(new JsonResult(-1, "退单号或订单号不能为空", new ResponseData()), SerializerFeatureUtil.FEATURES)));
		}

		Map<String, String> restmap = null;
		try {
			Map<String, String> parm = new HashMap<String, String>();
			parm.put("appid", APP_ID);
			parm.put("mch_id", MCH_ID);
			parm.put("transaction_id", tradeid);
//			parm.put("out_trade_no", tradeno);
//			parm.put("refund_id", refundid);
//			parm.put("out_refund_no", refundno);
			parm.put("nonce_str", PayUtil.getNonceStr());
			parm.put("sign", PayUtil.getSign(parm, API_SECRET));

			String restxml = HttpUtils.post(ORDER_REFUND_QUERY, XmlUtil.xmlFormat(parm, false));
			restmap = XmlUtil.xmlParse(restxml);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}

		Map<String, String> refundMap = new HashMap<>();
		if (CollectionUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code")) && "SUCCESS".equals(restmap.get("result_code"))) {
			// 订单退款查询成功 处理业务逻辑
			LOG.info("退款订单查询：订单" + restmap.get("out_trade_no") + "退款成功，退款状态"+ restmap.get("refund_status_0"));
			refundMap.put("transaction_id", restmap.get("transaction_id"));
			refundMap.put("out_trade_no", restmap.get("out_trade_no"));
			refundMap.put("refund_id", restmap.get("refund_id_0"));
			refundMap.put("refund_no", restmap.get("out_refund_no_0"));
			refundMap.put("refund_status", restmap.get("refund_status_0"));
//			WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//					.toJSONString(new JsonResult(1, "订单退款成功", new ResponseData(null, refundMap)), SerializerFeatureUtil.FEATURES)));
		} else {
			if (CollectionUtil.isNotEmpty(restmap)) {
				LOG.info("订单退款失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
			}
//			WebUtil.response(response, WebUtil.packJsonp(callback, JSON
//					.toJSONString(new JsonResult(-1, "订单退款失败", new ResponseData()), SerializerFeatureUtil.FEATURES)));
		}
	}

}
